﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EnvDTE;
using System.Timers;
using Microsoft.VisualStudio.Shell.Interop;
using Microsoft.VisualStudio.Shell;
using System.IO;

namespace dasFX.VSTime.API
{
    public class EventRecorder : IEventRecorder
    {
        private ISubmitEvent _submitter;
        private Timer _idleTimer;
        private OutputWindowPane _outputWindowPane;
        private bool _idled = false;
        private int _solutionId;
        private bool _running = false;
        private bool _projectOpen = false;
        private string _activeWindow;

        #region Constructors
        public EventRecorder(ISubmitEvent submitEvent, OutputWindowPane outputPane)
        {
            _submitter = submitEvent;
            _outputWindowPane = outputPane;
            StartIdleTimer();
        }
        #endregion

        #region Public Methods
        public void Solution_BeforeClosing(string SolutionFile)
        {
            if (SolutionFile != string.Empty)
            {
                _projectOpen = false;
                _submitter.RegisterEvent("SolutionClosing", SolutionFile);
            }
        }

        public void Solution_Opened(string SolutionFile)
        {
            if (SolutionFile != string.Empty)
            {
                _projectOpen = true;
                //Handle opening another solution while one is open
                _solutionId = _submitter.RegisterSolution(SolutionFile);
                _submitter.RegisterEvent("SolutionOpened", Path.GetFileName(SolutionFile));
            }
        }

        //Functions as a keep-alive, preventing the Idled event from registering while
        //the developer works in on a file
        public void Text_LineChanged(string Detail)
        {
            if (_idled)
            {
                _submitter.RegisterEvent("ReturnFromIdle", Detail);
                _idled = false;
            }
            //Reset idle timer
            _idleTimer.Stop();
            _idleTimer.Start();
        }

        public void Debug_OnEnterDesignMode(string Detail)
        {
            _running = false;
            if (_idled)
            {
                _idled = false;
                _idleTimer.Start();
                _idleTimer.Enabled = true;
            }
            _submitter.RegisterEvent("DesignModeEntered", Detail);
            //Record previously active window
            _submitter.RegisterEvent("ActiveWindow", _activeWindow);
        }


        public void Debug_OnExceptionThrown(string Detail)
        {
            _submitter.RegisterEvent("ExceptionThrown", Detail);
        }

        public void Debug_OnEnterRunMode(string Detail)
        {
            _running = true;
            _submitter.RegisterEvent("RunModeEntered", Detail);
        }

        public void Build_OnBuildDone(string Detail)
        {
            _submitter.RegisterEvent("BuildDone", Detail);
        }

        public void Build_OnBuildBegin(string Detail)
        {
            _submitter.RegisterEvent("BuildBegin", Detail);
        }

        /// <summary>
        /// Hook this to shutdown the EventManager and EventSink
        /// </summary>
        public void DTEEvents_OnBeginShutdown()
        {
            _submitter.RegisterEvent("IDEClosing", "IDEClosing");
            _submitter.Dispose();
        }

        public void Window_WindowCreated(string Detail)
        {
            _outputWindowPane.OutputString("WindowEvents::WindowCreated\n");
            _outputWindowPane.OutputString("\tWindow: " +
            Detail + "\n");
            if (_projectOpen)
            {
                _submitter.RegisterEvent("WindowCreated", Detail);
            }   
        }

        public void Document_DocumentOpening(string Detail)
        {
            _outputWindowPane.OutputString("Document Opening::" + Detail + "\n");
            if (_projectOpen)
            {
                _submitter.RegisterEvent("DocumentOpening", Path.GetFileName(Detail));
            }
        }

        public void Window_WindowClosing(string Detail)
        {
            _outputWindowPane.OutputString("WindowEvents::WindowClosing\n");
            _outputWindowPane.OutputString("\tWindow: " +
            Detail + "\n");
            if (_projectOpen)
            {
                _submitter.RegisterEvent("WindowClosing", Detail);
            }
        }

        public void Window_WindowActivated(string Detail)
        {
            _outputWindowPane.OutputString("WindowEvents::WindowActivated\n");
            _outputWindowPane.OutputString("\tWindow: " +
            Detail + "\n");
            if (_projectOpen)
            {
                _activeWindow = Detail;
                _submitter.RegisterEvent("WindowActivated", Detail);
            }
        }

        public void _idleTimer_Elapsed(object sender, ElapsedEventArgs e)
        {
            if (_projectOpen)
            {
                if (_running)
                {
                    _submitter.RegisterEvent("DEBUGIDLE", "DEBUGIDLE");
                }
                else
                {
                    _submitter.RegisterEvent("IDLE", "IDLE");
                }

                _idled = true;
                _idleTimer.Stop();
            }
        }

        private void StartIdleTimer()
        {
            //Start idle timer
            _idleTimer = new Timer();
            _idleTimer.Enabled = true;
            _idleTimer.Elapsed += new ElapsedEventHandler(_idleTimer_Elapsed);
            _idleTimer.Interval = 300000;   //5-minute timeout
            _idleTimer.AutoReset = false;
            _idleTimer.Start();
        }
        #endregion

       

        #region Public Properties
        public int SolutionID
        {
            get { return _solutionId; }
        }

        public bool Idled
        {
            get { return _idled; }
        }

        public bool Running
        {
            get { return _running; }
        }

        public bool ProjectOpen
        {
            get { return _projectOpen; }
        }

        #endregion








    }
}
